package com.datang.litejvm.loader;

import com.datang.litejvm.util.Util;

import java.util.Arrays;

/**
 * @author: 顶风少年
 * @Description: 迭代字节数组
 * @date: 13:50 2022/6/10
 **/
public class ByteCodeIterator {
    /**
     * @author: 顶风少年
     * @Description: 输入
     * @date: 13:51 2022/6/10
     **/
    byte[] codes;
    /**
     * @author: 顶风少年
     * @Description: 指针
     * @date: 13:51 2022/6/10
     **/
    int pos = 0;

    /**
     * @author: 顶风少年
     * @Description: 接受字节数组
     * @date: 13:51 2022/6/10
     **/
    ByteCodeIterator(byte[] codes) {
        this.codes = codes;
    }

    /**
     * @author: 顶风少年
     * @Description: 获取字节数组中的一部分, 会累加指针
     * @date: 13:52 2022/6/10
     **/
    public byte[] getBytes(int len) {
        if (pos + len >= codes.length) {
            throw new ArrayIndexOutOfBoundsException();
        }
        byte[] data = Arrays.copyOfRange(codes, pos, pos + len);
        pos += len;
        return data;
    }

    /**
     * @author: 顶风少年
     * @Description: 获取一个字节, 并转换成数字, 会累加指针
     * @date: 13:52 2022/6/10
     **/
    public int nextU1toInt() {
        return Util.byteToInt(new byte[]{codes[pos++]});
    }

    /**
     * @author: 顶风少年
     * @Description: 获取两个字节, 并转换成数字, 会累加指针
     * @date: 13:52 2022/6/10
     **/
    public int nextU2ToInt() {
        return Util.byteToInt(new byte[]{codes[pos++], codes[pos++]});
    }

    /**
     * @author: 顶风少年
     * @Description: 获取四个字节, 并转换成数字, 会累加指针
     * @date: 13:52 2022/6/10
     **/
    public int nextU4ToInt() {
        return Util.byteToInt(new byte[]{codes[pos++], codes[pos++], codes[pos++], codes[pos++]});
    }


    /**
     * @author: 顶风少年
     * @Description: 获取N个字节, 转换成字符串, 会累加指针,此方法会进行UNcode编码
     * @date: 13:52 2022/6/10
     **/
    public String nextUxToString(int len) {
        byte[] tmp = new byte[len];
        for (int i = 0; i < len; i++) {
            tmp[i] = codes[pos++];
        }
        return Util.byetToString(tmp);
    }

    /**
     * @author: 顶风少年
     * @Description: 获取N个字节, 转换成16进制字符串，指令表使用，会累加指针
     * @date: 13:52 2022/6/10
     **/
    public String nextUxToHexString(int len) {
        byte[] tmp = new byte[len];
        for (int i = 0; i < len; i++) {
            tmp[i] = codes[pos++];
        }
        return Util.byteToHexString(tmp);
    }

    /**
     * @author: 顶风少年
     * @Description: 获取四个字节, 转换成16进制字符串,魔数使用,会累加指针
     * @date: 13:52 2022/6/10
     **/
    public String nextU4ToHexString() {
        byte[] codes = new byte[]{this.codes[pos++], this.codes[pos++], this.codes[pos++], this.codes[pos++]};
        return Util.byteToHexString(codes);
    }

    /**
     * @author: 顶风少年
     * @Description: 回退字节
     * @date: 13:53 2022/6/10
     **/
    public void back(int n) {
        this.pos -= n;
    }
}
